
package com.xtsoft.platform.base.system.service.impl;


import com.xtsoft.core.repository.QueryResult;
import com.xtsoft.core.service.impl.GenericServiceImpl;
import com.xtsoft.core.utils.ResultMessage;
import com.xtsoft.core.utils.ResultMsg;
import com.xtsoft.core.utils.StringUtils;
import com.xtsoft.core.utils.tree.CommonTreeNode;
import com.xtsoft.core.utils.tree.TreeBuilder;
import com.xtsoft.platform.base.system.domain.SysOrganize;
import com.xtsoft.platform.base.system.domain.SysUser;
import com.xtsoft.platform.base.system.repository.*;
import com.xtsoft.platform.base.system.service.SysOrganizeService;
import com.xtsoft.platform.globe.Constants.Constants;
import com.xtsoft.platform.globe.enums.OrganizeType;
import com.xtsoft.platform.globe.enums.YesNo;
import com.xtsoft.platform.globe.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;



@Service("sysOrganizeService")
public class SysOrganizeServiceImpl extends GenericServiceImpl<SysOrganize,String,SysOrganizeRepository> implements SysOrganizeService {

	@Autowired
	public SysOrganizeRepository sysOrganizeRepository;
	
	@Autowired
	public SysUserRepository sysUserRepository;
	
	
	@Autowired
	public SysRoleRepository sysRoleRepository;
	
	@Autowired
	public SysTradeRepository sysTradeRepository;
	
	@Autowired
	public SysOrganizeTypeRepository sysOrganizeTypeRepository;
	

	/**
	 * 构建企业树
	 * @throws IntrospectionException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	@Override
	public List<CommonTreeNode> getOrganizeTree() throws NoSuchFieldException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
		SysUser user=(SysUser) SecurityUtils.getLoginedUser();
		int organizeType=user.getSysOrganize().getOrganizeType();
		List<SysOrganize> list = new ArrayList<SysOrganize>();
		SysOrganize rootNode = null;
		child.clear();
		if(organizeType==OrganizeType.VirtualOrganize.getIntValue() || organizeType== OrganizeType.Organize.getIntValue()){
			rootNode = new SysOrganize();
			rootNode.setOrganizeId(Constants.RootNode);
			rootNode.setOrganizeName("组织管理");
			list.addAll(sysOrganizeRepository.findByState(YesNo.Yes.getIntValue()));//所有启用机构
		}else{
			SysOrganize sysOrganize =user.getSysOrganize();
			rootNode = sysOrganize;
			List<SysOrganize> sysOrganizes = sysOrganizeRepository.findByParentNodeIdAndState(rootNode.getNodeId(), YesNo.Yes.getIntValue());
			if(null == sysOrganizes || sysOrganizes.size() == 0)
				getChildrenOrganize(sysOrganizes);
			list.addAll(child);
		}
		list.add(rootNode);		
		TreeBuilder<SysOrganize> treeBuilder = new TreeBuilder();
		List<CommonTreeNode> menuList = treeBuilder.build(list, "organizeId", "nodeId", "parentNodeId",
				"organizeName",null,null,null);
		return menuList;
	}
	List<SysOrganize> child = new ArrayList<>();
	/**
	 * 获取子企业集合
	 * @param sysOrganizes
	 */
	public void getChildrenOrganize(List<SysOrganize> sysOrganizes){
		child.addAll(sysOrganizes);
		for (SysOrganize sysOrganize : sysOrganizes) {
			String pid = sysOrganize.getNodeId();
			List<SysOrganize> childSysOrganizes = sysOrganizeRepository.findByParentNodeIdAndState(pid, YesNo.Yes.getIntValue());
			if(null != childSysOrganizes || childSysOrganizes.size() != 0)
				getChildrenOrganize(childSysOrganizes);
		}
	}
	
	@Override
	public ResultMsg removeOrganize(String id) {
		SysOrganize sysOrganize = sysOrganizeRepository.findById(id).orElse(null);
		if(null == sysOrganize) {
			return new ResultMsg(false,"选中的企业/部门不存在，可能已删除，请刷新再试");
		}
		List<SysOrganize> sysOrganizes= sysOrganizeRepository.findByParentNodeId(sysOrganize.getNodeId());
        if(sysOrganizes.size()==0) {
        	remove(id);
        	return new ResultMsg(true,"操作成功");
        }else {
        	return new ResultMsg(false,"该机构下存在子机构，请先删除子机构！");
        }
	}
	

	/**
	 * 禁用启用企业用户
	 */
	@SuppressWarnings("unused")
	@Override
	public ResultMessage enableOrDisable(String organizeIds) {
		String[] arrId=organizeIds.split(",");
		for (String organizeId : arrId) {
			SysOrganize sysOrganize=sysOrganizeRepository.getOne(organizeId);
			List<SysUser> sysUser = sysOrganize.getSysUsers();
			if(null==sysOrganize) continue;
			if(sysOrganize.getState()==YesNo.Yes.getIntValue()){
				sysOrganize.setState(YesNo.No.getIntValue());
				for (SysUser sysUser2 : sysUser) {
					sysUser2.setState(YesNo.No.getIntValue());
				}
			}else{
				sysOrganize.setState(YesNo.Yes.getIntValue());
				for (SysUser sysUser2 : sysUser) {
					sysUser2.setState(YesNo.Yes.getIntValue());
				}
			}
			List<SysOrganize> sysOrganizes=sysOrganizeRepository.findByParentNodeId(sysOrganize.getNodeId());
			sysOrganize.setList(sysOrganizes);
			for (int i = 0; i < sysOrganizes.size(); i++) {
				enableOrDisable(sysOrganizes.get(i).getOrganizeId());
			}
			sysOrganizeRepository.save(sysOrganize);
		}
		
		return new ResultMessage(true,"用户状态更改成功");
	}
	
	
	@Override
	public List<SysOrganize> getMultCombox(String tradeId) {
		StringBuffer buff=new StringBuffer();
		buff.append("(en.organizeType=0 or en.organizeType=1)");
		if(null!=tradeId) {
			buff.append(" and en.sysTrade.sysTradeId='"+tradeId+"'");
		}
		String orderBy="en.revenue DESC";
		return sysOrganizeRepository.findAll(SysOrganize.class, null, buff.toString(), orderBy);
	}
	
	/**
	 * 
	 * <p> 根据枚举获取该企业上级或者下级  </p>  
	 * @param sysOrganize
	 * @param commonTreeUd
	 * @param includSelf
	 * @return
	 * @return List<SysOrganize>
	 * @throws  
	 * @author wangyalin 
	 * @date 2019年12月9日 
	 * @time 上午11:30:38
	 */
	/*
	@Override
	public List<SysOrganize> getUpOrDown(SysOrganize sysOrganize, CommonTreeUd commonTreeUd,boolean includSelf) {
		List<SysOrganize> list = new ArrayList<>();
		if (commonTreeUd.equals(CommonTreeUd.Parent)) {//查找上级
			SysOrganize organize = sysOrganizeRepository.findByNodeIdAndState(sysOrganize.getNodeId(),OrganizeState.Using.getValue());
			list.add(organize);
			list = findParent(list,organize);
		}
		if (commonTreeUd.equals(CommonTreeUd.Children)) {//查找下级
			list = sysOrganizeRepository.findByParentNodeIdAndState(sysOrganize.getNodeId(), OrganizeState.Using.getValue());
			int level = 0;
			sysOrganize.setLevel(level);
			level++;
			list = findChildren(list,level);
		}
		if (includSelf) {
			list.add(sysOrganize);
		}
		return list;
	}
	*/

	
	/**
	 * 
	 * <p> 递归找下级 </p>  
	 * @param list
	 * @return
	 * @return List<SysOrganize>
	 * @throws  
	 * @author wangyalin 
	 * @date 2019年12月9日 
	 * @time 下午12:18:05
	 */
	private List<SysOrganize> findChildren(List<SysOrganize> list,int level) {
		List<SysOrganize> childList = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			SysOrganize sysOrganize = list.get(i);
			sysOrganize.setLevel(level);
			List<SysOrganize> sysOrganizeList = sysOrganizeRepository.findByParentNodeIdAndState(sysOrganize.getNodeId(), YesNo.Yes.getIntValue());
			if (sysOrganizeList.size()==0) {
				continue;
			}else {
				childList.addAll(findChildren(sysOrganizeList,level+1));
			}
		}
		list.addAll(childList);
		return list;
	}
	/**
	 * 
	 * <p> 递归找上级  </p>  
	 * @param list
	 * @param sysOrganize
	 * @return
	 * @return List<SysOrganize>
	 * @throws  
	 * @author wangyalin 
	 * @date 2019年12月9日 
	 * @time 上午11:57:45
	 */
	private List<SysOrganize> findParent(List<SysOrganize> list, SysOrganize sysOrganize) {
		//说明已经到达了顶端,虚拟组织类
		if (sysOrganize.getOrganizeId().equals(Constants.RootNode)) {
			return list;
		}
		//遍历集合递归找上级
		SysOrganize organize = sysOrganizeRepository.findByNodeIdAndState(sysOrganize.getParentNodeId(), YesNo.Yes.getIntValue());
		list.add(organize);
		return findParent(list, organize);
	}
	
	/**
	 * 
	 * <p> 递归生成nodeId、parNodeIde指向关系  </p>  
	 * @param nodeNum
	 * @param parentOrganizes
	 * @param organize 
	 * @return void
	 * @throws  
	 * @author wangyalin 
	 * @date 2019年12月11日 
	 * @time 上午10:35:28
	 */
	private void setNodeId(int nodeNum, List<SysOrganize> parentOrganizes, SysOrganize organize) {
		for (int i = 0; i < parentOrganizes.size(); i++) {
			SysOrganize sysOrganize = parentOrganizes.get(i);
			sysOrganize.setParentNodeId(organize.getNodeId());
			if (!organize.getNodeId().equals(Constants.RootNode)) {//虚拟组织下级
				sysOrganize.setNodeId(organize.getNodeId()+String.format("%06d", nodeNum));
			}else{
				sysOrganize.setNodeId(String.format("%06d", nodeNum));
			}
			sysOrganizeRepository.save(sysOrganize);
			nodeNum++;
			List<SysOrganize> list = sysOrganizeRepository.findByParentNodeId(sysOrganize.getNodeId());
			if (list.size()>0) {
				setNodeId(1,list,sysOrganize);
			}
		}
		
	}

	@Override
	public String getOrganizeTree(Integer isShowDept, Integer isHideState, Integer isCheckedBox) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, IntrospectionException {
		// TODO Auto-generated method stub
		StringBuffer buff = new StringBuffer();
		String whereJpql = null;
		if(isShowDept == YesNo.No.getIntValue()) {
			buff.append(" (en.organizeType =" +  YesNo.No.getIntValue() + "");
		}else {
			buff.append(" (en.organizeType <>" + OrganizeType.VirtualOrganize.getIntValue() + "");
		}
		buff.append(")");
		if(isHideState == YesNo.No.getIntValue()) {
			buff.append("AND (en.state ='" +  YesNo.Yes.getIntValue() + "'");
			buff.append(")");
		}
		SysUser user=(SysUser) SecurityUtils.getLoginedUser();
		int organizeType=user.getSysOrganize().getOrganizeType();
		QueryResult<SysOrganize> organizeList = null;
		//如果当前用户不是超级管理员那么只能看到自己企业下的企业或者部门
		if(organizeType!=OrganizeType.VirtualOrganize.getIntValue()){
			buff.append("AND (en.nodeId  like '"+user.getSysOrganize().getNodeId()+"%'");
			buff.append(")");
		}
		whereJpql = buff.toString();
		organizeList = sysOrganizeRepository.findAll(SysOrganize.class, 0, 10000, whereJpql, null, null);
		StringBuffer buffs=new StringBuffer("[{\"id\":\""+Constants.RootNode+"\",\"text\":\"单位管理\",\"iconCls\":\"x-fa fa-th-list\",\"expanded\": true,\"leaf\":false,\"children\":");
		if(isCheckedBox == YesNo.Yes.getIntValue()) {
			//如果需要复选框
			String TreeResource[] = {"NodeId","ParentNodeId","OrganizeName","OrganizeType","","","","Checked"};
			TreeBuilder<SysOrganize> treeBuilder = new TreeBuilder<SysOrganize>();
		//	buffs.append(treeBuilder.buildTree(organizeList.getResultList(),TreeResource,SysOrganize.class)).append("}]");

		}else {
			//StringBuffer buffs=new StringBuffer("[{\"id\":\"00\",\"text\":\"单位管理\",\"iconCls\":\"x-fa fa-th-list\",\"expanded\": true,\"leaf\":false,\"children\":");
			String TreeResource[] = {"NodeId","ParentNodeId","OrganizeName","OrganizeType","","",""};
			TreeBuilder<SysOrganize> treeBuilder = new TreeBuilder<SysOrganize>();
			//buffs.append(treeBuilder..buildTree(organizeList.getResultList(),TreeResource,SysOrganize.class)).append("}]");
		}
		
		
		return buffs.toString();
	}

	@Override
	public void addSysOrganize(SysOrganize sysOrganize) {
		// TODO Auto-generated method stub
		// 生成nodeId
		String nodeId = "";
//		if(sysOrganize.getParentNodeId().equals(Constants.RootNode)) {
//			nodeId = NodeUtils.createNodeIdWithParent(sysOrganizeRepository.findMaxNodeId(sysOrganize.getParentNodeId()),sysOrganize.getParentNodeId(),Constants.CodeLength,true,true);
//		}else {
//			nodeId = NodeUtils.createNodeIdWithParent(sysOrganizeRepository.findMaxNodeId(sysOrganize.getParentNodeId()),sysOrganize.getParentNodeId(),Constants.CodeLength,true,false);
//		}
		if(StringUtils.isEmpty(sysOrganize.getSerialNo())) {
			//找到父节点下子节点的最大排序号
			Integer serialNo = sysOrganizeRepository.findSerialNoByParentNodeIdMax(sysOrganize.getParentNodeId());
			if(StringUtils.isEmpty(serialNo)){
				sysOrganize.setSerialNo(1);
			}else {
				sysOrganize.setSerialNo(serialNo+1);
			}
			
		}
		sysOrganize.setSysOrganizeType(sysOrganizeTypeRepository.findByNodeId(sysOrganize.getSysOrganizeType().getNodeId()));
		sysOrganize.setNodeId(nodeId);
	}

	@Override
	public void updateSysOrganize(SysOrganize sysOrganize,SysOrganize result) {
		// TODO Auto-generated method stub
		if(!sysOrganize.getParentNodeId().equals(result.getParentNodeId())) {
			//如果不一样
			String nodeId = "";
//			if(sysOrganize.getParentNodeId().equals(Constants.RootNode)) {
//				nodeId = NodeUtils.createNodeIdWithParent(sysOrganizeRepository.findMaxNodeId(sysOrganize.getParentNodeId()),sysOrganize.getParentNodeId(),Constants.CodeLength,true,true);
//			}else {
//				nodeId = NodeUtils.createNodeIdWithParent(sysOrganizeRepository.findMaxNodeId(sysOrganize.getParentNodeId()),sysOrganize.getParentNodeId(),Constants.CodeLength,true,false);
//			}
			
			sysOrganize.setNodeId(nodeId);
		}
		sysOrganize.setSysOrganizeType(sysOrganizeTypeRepository.findByNodeId(sysOrganize.getSysOrganizeType().getNodeId()));
		//sysOrganize.setSysTrade(sysTradeRepository.getOne(sysOrganize.getSysTrade().getSysTradeId()));
	}

	@Override
	public SysOrganize getByNodeId(String nodeId) {
		// TODO Auto-generated method stub
		return sysOrganizeRepository.findByNodeId(nodeId);
	}

	@Override
	public SysOrganize getByNodeIdAndState(String nodeId, Integer state) {
		// TODO Auto-generated method stub
		return sysOrganizeRepository.findByNodeIdAndState(nodeId, state);
	}

	@Override
	public List<SysOrganize> getByParentNodeIdAndState(String parentNodeId, Integer state) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<SysOrganize> findBySysOrganizeTypeId(String id) {
		// TODO Auto-generated method stub
		return sysOrganizeRepository.findBySysOrganizeTypeOrganizeTypeId(id);
	}
	
	
	
	
	

}